#include"ThreadPool.h"


Task::Task()
{
}
Task::Task(callback f1,void*arg1):f(f1),arg(arg1){

}


ThreadPool::ThreadPool(int threadnum,int threadpoolmaxnum)
{
    isstart=true;              
    StartThreadNum=threadnum;        
    LeisureThreadNum=threadnum;   
    BusyThreadNum=0;
    GeneralThreadNum=threadnum;
    ThreadPoolMaxNum=threadpoolmaxnum;       //线程数量最大的上线
    this->StartThreadPool(threadnum);
    thread*pa=new thread(ManageThread,this);  //启动管理者线程   
}

ThreadPool::~ThreadPool()
{
     this->isstart=false;
     this->cond.notify_all();  //唤醒全部线程   析构

     for(int i=0;i<workerthread.size();i++){  //处理掉剩下的线程
        if(workerthread[i]==nullptr){
            continue;
        }
        workerthread[i]->detach();  
     }
}

void ThreadPool::StartThreadPool(int ThreadNum)
{
     for(int i=0;i<ThreadNum;i++){
         thread *pa=new thread(ThreadPoolFuntion,this);
         //thread pa(ThreadPoolFuntion,this);
         workerthread.push_back(pa);
     }
}

void ThreadPool::addTask(Task t)
{
    {
      unique_lock<mutex> lock(mtx);
      task_queue.push(t);
    }
    cond.notify_one();
}

void ThreadPool::addTask(callback f, void *arg)
{
    {
      unique_lock<mutex> lock(mtx);
      task_queue.push(Task(f,arg));
    }
    cond.notify_one();
}

void ThreadPool::ThreadPooljoin()
{
     for(int i=0;i<this->workerthread.size();i++){
          if(workerthread[i]==nullptr){
            continue;
          }
          workerthread[i]->join();
     }
}


void ThreadPool::ThreadPoolFuntion(ThreadPool *pool)
{
    pool->worker_mtx.lock();
    cout<<"启动成功"<<this_thread::get_id()<<endl;
    pool->worker_mtx.unlock();
    while(pool && pool->isstart){
        Task task;
        {
            unique_lock<mutex>lck(pool->mtx);
            if(pool->task_queue.empty()){
                pool->cond.wait(lck);
            }
            if(pool->task_queue.empty()){
                cout<<"杀死了一个线程:"<<this_thread::get_id()<<endl;
                break;
            }
            task=pool->task_queue.front();
            pool->task_queue.pop();
        }
        pool->management_mtx.lock();    //开始处理任务 空闲线程--
        pool->LeisureThreadNum--;
        pool->management_mtx.unlock();

        task.f(task.arg);

        pool->management_mtx.lock();   //任务处理完成 空闲线程++
        pool->LeisureThreadNum++;
        pool->management_mtx.unlock();
    } 
    if(pool){   //当这个线程池实列被析构掉后直接return
        return ;
    }
    //线程退出  //将workerthread数组中的地址指为0;
    {
        unique_lock<mutex>lck(pool->worker_mtx);
        for(int i=0;i<pool->workerthread.size();i++){
            if(pool->workerthread[i]==nullptr){
                continue;
            }
            if(pool->workerthread[i]->get_id()==this_thread::get_id()){
                //将当前线程
                pool->workerthread[i]=nullptr;
                pool->GeneralThreadNum--;  //总的线程数
                 pool->LeisureThreadNum--;  //空闲线程--
                break;
            }
        }
    }
}
void ThreadPool::ManageThread(ThreadPool *pool)   //管理着线程
{
    //线程池自动控制线程数量  增加条件 当   总线程/工作线程的数量=0.9以上
    //减少条件     减少最少线程数量必须大于起始线程数量  减少条件 （当前空闲线程数/工作线程数=0.9）
    while(pool->isstart){
          pool->worker_mtx.lock();
          cout<<"线程总数"<<pool->GeneralThreadNum<<" "<<"空闲总数"<<pool->LeisureThreadNum<<endl;
          pool->worker_mtx.unlock();
          sleep(5);  //10s 检测一次

          double threadnum=pool->GeneralThreadNum;   //线程总数
          double Leisurenum=pool->LeisureThreadNum;  //空闲数目

          double num=0.0001;
          num=Leisurenum/threadnum;
           //减少 线程数   1.判断当前线程数是都是起始线程数 是 不用减少
          if(num>=0.9 && threadnum>=pool->StartThreadNum){      
               int tempnum=threadnum/2;//减少线程数 百分之五十
               if((threadnum-tempnum)>pool->StartThreadNum){  //大于起始线程数 就减少tempnum数量的线程数
                    for(int i=0;i<tempnum;i++){
                        pool->cond.notify_one();
                    }
                    pool->management_mtx.lock();
                    pool->GeneralThreadNum-=tempnum;
                    pool->LeisureThreadNum-=tempnum;
                    pool->management_mtx.unlock();
               }
               else{    //小于起始线程数 减少到起始线程数不能在减了
                   int tempnum=threadnum;//减少线程数 百分之五十
                   while(tempnum>pool->StartThreadNum){
                       pool->cond.notify_one();
                       tempnum--;
                   }
                    pool->management_mtx.lock();
                    pool->GeneralThreadNum-=tempnum;
                    pool->LeisureThreadNum-=tempnum;
                    pool->management_mtx.unlock();
               }
          }
          //线程是空闲线程小于0.1 增加线程池的数量
          if(num<=0.1 && threadnum>=pool->StartThreadNum){
              int tempnum=threadnum+threadnum/2;   //增加线程数 百分之五十
              
              //防止大于最大线程数 
              if((tempnum+threadnum)>pool->ThreadPoolMaxNum){
                  tempnum=pool->ThreadPoolMaxNum-tempnum+threadnum;
              }

              //增加线程
              pool->StartThreadPool(tempnum);
              pool->management_mtx.lock();
              pool->GeneralThreadNum+=tempnum;
              pool->LeisureThreadNum+=tempnum;
              pool->management_mtx.unlock();

          }
    }
   
}
